Fixed dashed line issues (#74441) to an IMO reasonable extend. That is:
authorHans Breuer <hans@breuer.org>
Thu, 28 Mar 2002 23:25:33 +0000 (23:25 +0000)
committerHans Breuer <hans@src.gnome.org>
Thu, 28 Mar 2002 23:25:33 +0000 (23:25 +0000)
2002-03-29  Hans Breuer  <hans@breuer.org>

Fixed dashed line issues (#74441) to an IMO reasonable extend.
That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
to be with lines width > 50); Render horizontal and vertical
dashed lines on Win9x 'by hand'. Dotted selection rectangles
and Dia look nice ...

* gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
num_pen_dashes to _GdkGCWin32
* gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
the guesses from dashes to windoze line styles.
(predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
Win9x, which does not support PS_USERSTYLE.
* gdk/win32/gdkdrawable-win32.c : new functions render_line_
<horizontal|vertical>. Use them if not running on NT in
gdk_win32_draw_<rectangle|segments|lines> ()

* gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
for keyval == 0 to avoid to have zeros in all menu entries
without accelerator.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/win32/gdkdrawable-win32.c
gdk/win32/gdkgc-win32.c
gdk/win32/gdkkeys-win32.c
gdk/win32/gdkprivate-win32.h

index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index 2ff5812ae9ffd662b38ee9f3fab0d8487c410772..8d0fcaffacd51a27a134fc64eaf97e24388df3a1 100644 (file)
@@ -1,3 +1,25 @@
+2002-03-29  Hans Breuer  <hans@breuer.org>
+
+       Fixed dashed line issues (#74441) to an IMO reasonable extend. 
+       That is: use PS_USERSTYLE on WinNT (the next GDI limit appears
+       to be with lines width > 50); Render horizontal and vertical
+       dashed lines on Win9x 'by hand'. Dotted selection rectangles 
+       and Dia look nice ...
+
+       * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and
+       num_pen_dashes to _GdkGCWin32
+       * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove
+       the guesses from dashes to windoze line styles.
+       (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on
+       Win9x, which does not support PS_USERSTYLE.
+       * gdk/win32/gdkdrawable-win32.c : new functions render_line_
+       <horizontal|vertical>. Use them if not running on NT in
+       gdk_win32_draw_<rectangle|segments|lines> ()
+
+       * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL
+       for keyval == 0 to avoid to have zeros in all menu entries 
+       without accelerator.
+
 2002-03-29  Jakub Steiner <jimmac@ximian.com>
 
        * gtk/stock-icons/stock_add_24.png:
index a4dc7298b08a346787ca7288576e71634a2b0548..62b9c3f9d41062530418b9ed11a167ddb9a95054 100644 (file)
@@ -250,6 +250,69 @@ gdk_win32_set_colormap (GdkDrawable *drawable,
 /* Drawing
  */
 
+/*
+ * Render a dashed line 'by hand' cause the Win9x GDI is 
+ * too limited to do so
+ */
+static inline gboolean
+render_line_horizontal (HDC hdc,
+                        int x1, 
+                        int x2,
+                        int y,
+                        int pen_width,
+                        int *dashes,
+                        int num_dashes)
+{
+  int n;
+  for (n = 0; x1 < x2; n++)
+    {
+      int len = dashes[n % num_dashes];
+      if (x1 + len > x2)
+        len = x2 - x1;
+
+      if (n % 2 == 0)
+        if (!PatBlt (hdc,
+                     x1, y - pen_width / 2, 
+                     len, pen_width, 
+                     PATCOPY))
+          {
+            WIN32_GDI_FAILED ("PatBlt");
+            return FALSE;
+          }
+
+      x1 += dashes[n % num_dashes];
+    }
+}
+
+
+static inline gboolean
+render_line_vertical (HDC hdc,
+                        int x, 
+                        int y1,
+                        int y2,
+                        int pen_width,
+                        int *dashes,
+                        int num_dashes)
+{
+  int n;
+  for (n = 0; y1 < y2; n++)
+    {
+      int len = dashes[n % num_dashes];
+      if (y1 + len > y2)
+        len = y2 - y1;
+      if (n % 2 == 0)
+        if (!PatBlt (hdc, 
+                     x - pen_width / 2, y1, 
+                     pen_width, len, 
+                     PATCOPY))
+          {
+            WIN32_GDI_FAILED ("PatBlt");
+            return FALSE;
+          }
+      y1 += dashes[n % num_dashes];
+    }
+}
+
 static void
 gdk_win32_draw_rectangle (GdkDrawable *drawable,
                          GdkGC       *gc,
@@ -341,16 +404,38 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable,
     }
   else
     {
-      if (filled)
-       old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN));
-      else
-       old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
-      if (old_pen_or_brush == NULL)
-       WIN32_GDI_FAILED ("SelectObject");
-      else if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
-       WIN32_GDI_FAILED ("Rectangle");
+      if (!filled && gc_private->pen_dashes && !IS_WIN_NT ())
+        {
+          ok = ok && render_line_vertical (hdc, x, y, y+height+1,
+                                           gc_private->pen_width,
+                                           gc_private->pen_dashes,
+                                           gc_private->pen_num_dashes);
+          ok = ok && render_line_horizontal (hdc, x, x+width+1, y,
+                                             gc_private->pen_width,
+                                             gc_private->pen_dashes,
+                                             gc_private->pen_num_dashes);
+          ok = ok && render_line_vertical (hdc, x+width+1, y, y+height+1,
+                                           gc_private->pen_width,
+                                           gc_private->pen_dashes,
+                                           gc_private->pen_num_dashes);
+          ok = ok && render_line_horizontal (hdc, x, x+width+1, y+height+1,
+                                             gc_private->pen_width,
+                                             gc_private->pen_dashes,
+                                             gc_private->pen_num_dashes);
+        }
       else
-       SelectObject (hdc, old_pen_or_brush);
+        {
+          if (filled)
+            old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN));
+          else
+            old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
+          if (old_pen_or_brush == NULL)
+            WIN32_GDI_FAILED ("SelectObject");
+          if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
+            WIN32_GDI_FAILED ("Rectangle");
+          if (old_pen_or_brush)
+            SelectObject (hdc, old_pen_or_brush);
+        }
     }
 
   gdk_win32_hdc_release (drawable, gc, mask);
@@ -771,57 +856,112 @@ gdk_win32_draw_segments (GdkDrawable *drawable,
     }
   else
     {
-      const gboolean maybe_patblt =
-       gc_private->rop2 == R2_COPYPEN &&
-       gc_private->pen_width <= 1 &&
-       (gc_private->pen_style & PS_STYLE_MASK) == PS_SOLID;
-
-      for (i = 0; ok && i < nsegs; i++)
-       {
-         /* PatBlt() is much faster than LineTo(), says
-           * jpe@archaeopteryx.com. Hmm. Use it if we have a solid
-           * colour pen, then we know that the brush is also solid and
-           * of the same colour.
-          */
-         if (maybe_patblt && segs[i].x1 == segs[i].x2)
+      if (gc_private->pen_dashes && !IS_WIN_NT ())
+        {
+          /* code very similar to the IMHO questionable optimization 
+           * below. This one draws dashed vertical/horizontal lines 
+           * with the limited Win9x GDI.                        --hb
+           */
+          for (i = 0; ok && i < nsegs; i++)
             {
-             int y1, y2;
-
-             if (segs[i].y1 <= segs[i].y2)
-               y1 = segs[i].y1, y2 = segs[i].y2;
-             else
-               y1 = segs[i].y2, y2 = segs[i].y1;
-
-              if (!PatBlt (hdc, segs[i].x1, y1,
-                          1, y2 - y1 + 1, PATCOPY))
-                WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
+               if (segs[i].x1 == segs[i].x2)
+                {
+                  int y1, y2;
+
+                  if (segs[i].y1 <= segs[i].y2)
+                    y1 = segs[i].y1, y2 = segs[i].y2;
+                  else
+                    y1 = segs[i].y2, y2 = segs[i].y1;
+
+                  ok = render_line_vertical (hdc,
+                                             segs[i].x1, y1, y2,
+                                             gc_private->pen_width,
+                                             gc_private->pen_dashes,
+                                             gc_private->pen_num_dashes);
+                }
+              else if (segs[i].y1 == segs[i].y2)
+                {
+                  int x1, x2;
+
+                  if (segs[i].x1 <= segs[i].x2)
+                    x1 = segs[i].x1, x2 = segs[i].x2;
+                  else
+                    x1 = segs[i].x2, x2 = segs[i].x1;
+
+                  ok = render_line_horizontal (hdc,
+                                               x1, x2, segs[i].y1,
+                                               gc_private->pen_width,
+                                               gc_private->pen_dashes,
+                                               gc_private->pen_num_dashes);
+                }
+              else
+                {
+                  if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
+                    WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
+                  if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
+                    WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+         
+                  /* Draw end pixel */
+                  if (ok && gc_private->pen_width <= 1)
+                    if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
+                      WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+                }
             }
-         else if (maybe_patblt && segs[i].y1 == segs[i].y2)
-            {
-             int x1, x2;
-
-             if (segs[i].x1 <= segs[i].x2)
-               x1 = segs[i].x1, x2 = segs[i].x2;
-             else
-               x1 = segs[i].x2, x2 = segs[i].x1;
+        }
+      else
+        {
+          const gboolean maybe_patblt =
+            gc_private->rop2 == R2_COPYPEN &&
+            gc_private->pen_width <= 1 &&
+            (gc_private->pen_style & PS_STYLE_MASK) == PS_SOLID;
 
-              if (!PatBlt (hdc, x1, segs[i].y1,
-                          x2 - x1 + 1, 1, PATCOPY))
-                WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
-            }
-          else
+          for (i = 0; ok && i < nsegs; i++)
             {
-             if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
-               WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
-             if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
-               WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
-         
-             /* Draw end pixel */
-             if (ok && gc_private->pen_width <= 1)
-               if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
-                 WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+              /* PatBlt() is much faster than LineTo(), says
+               * jpe@archaeopteryx.com. Hmm. Use it if we have a solid
+               * colour pen, then we know that the brush is also solid and
+               * of the same colour.
+                */
+               if (maybe_patblt && segs[i].x1 == segs[i].x2)
+                {
+                  int y1, y2;
+
+                  if (segs[i].y1 <= segs[i].y2)
+                    y1 = segs[i].y1, y2 = segs[i].y2;
+                  else
+                    y1 = segs[i].y2, y2 = segs[i].y1;
+
+                  if (!PatBlt (hdc, segs[i].x1, y1,
+                               1, y2 - y1 + 1, PATCOPY))
+                    WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
+                }
+              else if (maybe_patblt && segs[i].y1 == segs[i].y2)
+                {
+                  int x1, x2;
+
+                  if (segs[i].x1 <= segs[i].x2)
+                    x1 = segs[i].x1, x2 = segs[i].x2;
+                  else
+                    x1 = segs[i].x2, x2 = segs[i].x1;
+
+                  if (!PatBlt (hdc, x1, segs[i].y1,
+                               x2 - x1 + 1, 1, PATCOPY))
+                    WIN32_GDI_FAILED ("PatBlt"), ok = FALSE;
+                }
+              else
+                {
+                  if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
+                    WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
+                  if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
+                    WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+         
+                  /* Draw end pixel */
+                  if (ok && gc_private->pen_width <= 1)
+                    if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
+                      WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+                }
             }
-       }
+         }
     }
   gdk_win32_hdc_release (drawable, gc, mask);
 }
@@ -844,26 +984,69 @@ gdk_win32_draw_lines (GdkDrawable *drawable,
 
   hdc = gdk_win32_hdc_get (drawable, gc, mask);
 
-  pts = g_new (POINT, npoints);
-
-  for (i = 0; i < npoints; i++)
+  if (gc_private->pen_dashes && !IS_WIN_NT ())
     {
-      pts[i].x = points[i].x;
-      pts[i].y = points[i].y;
+      for (i = 0; i < npoints - 1; i++)
+        {
+         if (points[i].x == points[i+1].x)
+           {
+             int y1, y2;
+             if (points[i].y > points[i+1].y)
+               y1 = points[i+1].y, y2 = points[i].y;
+             else
+               y1 = points[i].y, y2 = points[i+1].y;
+
+             render_line_vertical (hdc, points[i].x, y1, y2,
+                                   gc_private->pen_width,
+                                   gc_private->pen_dashes,
+                                   gc_private->pen_num_dashes);
+           }
+         else if (points[i].y == points[i+1].y)
+           {
+             int x1, x2;
+             if (points[i].x > points[i+1].x)
+               x1 = points[i+1].x, x2 = points[i].x;
+             else
+               x1 = points[i].x, x2 = points[i+1].x;
+
+             render_line_horizontal (hdc, x1, x2, points[i].y,
+                                     gc_private->pen_width,
+                                     gc_private->pen_dashes,
+                                     gc_private->pen_num_dashes);
+           }
+         else
+           {
+             if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
+               WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
+             if (ok && !LineTo (hdc, points[i+1].x, points[i+1].y))
+               WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
+           }
+       }
     }
+  else
+    {
+      pts = g_new (POINT, npoints);
+
+      for (i = 0; i < npoints; i++)
+       {
+         pts[i].x = points[i].x;
+         pts[i].y = points[i].y;
+       }
   
-  if (!Polyline (hdc, pts, npoints))
-    WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
+      if (!Polyline (hdc, pts, npoints))
+       WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
   
-  g_free (pts);
+      g_free (pts);
   
-  /* Draw end pixel */
-  if (ok && gc_private->pen_width <= 1)
-    {
-      MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
-      if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
-       WIN32_GDI_FAILED ("LineTo");
+      /* Draw end pixel */
+      if (ok && gc_private->pen_width <= 1)
+       {
+         MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
+         if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
+           WIN32_GDI_FAILED ("LineTo");
+       }
     }
+
   gdk_win32_hdc_release (drawable, gc, mask);
 }
 
index cefdfd9c98c6ea3e502f89ce7d7e2247545fc47e..4d3a04f1ec88653c9f7d9ed9ba4ac6a322e1dc41 100644 (file)
@@ -107,6 +107,9 @@ gdk_gc_win32_finalize (GObject *object)
   
   if (win32_gc->values_mask & GDK_GC_STIPPLE)
     gdk_drawable_unref (win32_gc->stipple);
+
+  if (win32_gc->pen_dashes)
+    g_free (win32_gc->pen_dashes);
   
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -363,23 +366,30 @@ gdk_win32_gc_values_to_win32values (GdkGCValues    *values,
       switch (values->line_style)
        {
        case GDK_LINE_SOLID:
-        win32_gc->pen_style &= ~(PS_STYLE_MASK);
+         if (win32_gc->pen_dashes)
+           {
+             g_free (win32_gc->pen_dashes);
+             win32_gc->pen_dashes = NULL;
+            win32_gc->pen_num_dashes = 0;
+           }
+          win32_gc->pen_style &= ~(PS_STYLE_MASK);
          GDK_NOTE (GC, (g_print ("%sps|=LINE_SOLID", s),
                         s = ","));
          win32_gc->pen_style |= PS_SOLID;
          break;
        case GDK_LINE_ON_OFF_DASH:
-       case GDK_LINE_DOUBLE_DASH: /* ??? */
-         /* Only set the linestyle here, if it isn't already set
-          * gdk_win32_gc_set_dashes () knows better
-          */
-         if (0 == (win32_gc->values_mask & GDK_GC_LINE_STYLE))
+       case GDK_LINE_DOUBLE_DASH: 
+         if (!win32_gc->pen_dashes)
            {
+            /* setting to PS_DASH probably isn't correct. If I understand the
+             * xlib docs correctly it should influence the handling of
+             * line endings ? --hb
+             */
             win32_gc->pen_style &= ~(PS_STYLE_MASK);
-             GDK_NOTE (GC, (g_print ("%sps|=DASH", s),
-                            s = ","));
-             win32_gc->pen_style |= PS_DASH;
-           }
+             GDK_NOTE (GC, (g_print ("%sps|=DASH", s),
+                                    s = ","));
+             win32_gc->pen_style |= PS_DASH;
+          }
          break;
        }
       win32_gc->values_mask |= GDK_GC_LINE_STYLE;
@@ -468,6 +478,8 @@ _gdk_win32_gc_new (GdkDrawable        *drawable,
   win32_gc->stipple = NULL;
   win32_gc->pen_style = PS_GEOMETRIC|PS_ENDCAP_FLAT|PS_JOIN_MITER;
   win32_gc->pen_width = 0;
+  win32_gc->pen_dashes = NULL;
+  win32_gc->pen_num_dashes = 0;
 
   win32_gc->values_mask = GDK_GC_FUNCTION | GDK_GC_FILL;
 
@@ -586,6 +598,7 @@ gdk_win32_gc_set_dashes (GdkGC *gc,
                         gint   n)
 {
   GdkGCWin32 *win32_gc;
+  int i;
 
   g_return_if_fail (GDK_IS_GC (gc));
   g_return_if_fail (dash_list != NULL);
@@ -597,61 +610,11 @@ gdk_win32_gc_set_dashes (GdkGC *gc,
 
   win32_gc->pen_style &= ~(PS_STYLE_MASK);
 
-  /* 
-   * Set the extended line style. This could be done by 
-   * PS_USERSTYLE and ExtCreatePen; but ONLY on WinNT, 
-   * so let's make a guess (based on the implementation 
-   * in DIA). On Win9x this does only work for lines
-   * with width one ...
-   *
-   * More workarounds for Win9x descibed at:
-   * http://www.codeguru.com/gdi/dashed.shtml
-   */
-  if (!IS_WIN_NT () && win32_gc->pen_width > 1)
-    {
-      GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: not fully supported\n"));
-      win32_gc->pen_style |= PS_SOLID;
-      return;
-    }
-  
-  win32_gc->pen_style &= ~PS_STYLE_MASK;
-  switch (n)
-    {
-    case 2:
-      if ((dash_list[0] == dash_list[1]) && (dash_list[0] > 2))
-        {
-          win32_gc->pen_style |= PS_DASH;
-          GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASH (%d,%d)\n", 
-                                dash_list[0], dash_list[1]));
-        }
-      else
-        {
-          win32_gc->pen_style |= PS_DOT;
-          GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DOT (%d,%d)\n",
-                                dash_list[0], dash_list[1]));
-        }
-      break;
-
-    case 4:
-      win32_gc->pen_style |= PS_DASHDOT; 
-      GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASHDOT (%d,%d,%d,%d)\n", 
-                            dash_list[0], dash_list[1],
-                            dash_list[2], dash_list[3]));
-      break;
-
-    case 6:
-      win32_gc->pen_style |= PS_DASHDOTDOT; 
-      GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASHDOTDOT (%d,%d,%d,%d,%d,%d)\n", 
-                            dash_list[0], dash_list[1],
-                            dash_list[2], dash_list[3],
-                            dash_list[4], dash_list[5]));
-      break;
-
-    default:
-      win32_gc->pen_style |= PS_DASH;
-      GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: no guess for %d dashes\n", n));
-      break;
-    }
+  win32_gc->pen_style |= (PS_GEOMETRIC | PS_USERSTYLE);
+  win32_gc->pen_num_dashes = n;
+  win32_gc->pen_dashes = g_new (DWORD, n);
+  for (i = 0; i < n; i++)
+    win32_gc->pen_dashes[i] = dash_list[i];
 }
 
 void
@@ -752,9 +715,14 @@ gdk_gc_copy (GdkGC *dst_gc,
     gdk_region_destroy (dst_win32_gc->clip_region);
   if (dst_win32_gc->hcliprgn != NULL)
     DeleteObject (dst_win32_gc->hcliprgn);
+  if (dst_win32_gc->pen_dashes)
+    g_free (dst_win32_gc->pen_dashes);
   
   *dst_win32_gc = *src_win32_gc;
 
+  if (dst_win32_gc->pen_dashes)
+    dst_win32_gc->pen_dashes = g_memdup (src_win32_gc->pen_dashes, 
+                                         sizeof (DWORD) * src_win32_gc->pen_num_dashes);
   if (dst_win32_gc->hcliprgn)
     {
       /* create a new region, to copy to */
@@ -856,10 +824,28 @@ predraw_set_foreground (GdkGC       *gc,
   logbrush.lbColor = fg;
   logbrush.lbHatch = 0;
 
-  if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style,
-                                  (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
-                                  &logbrush, 0, NULL)) == NULL)
-    WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
+  if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ())
+    {
+      /* The Win9x GDI is rather limited so we either draw dotted
+       * lines ourselve (only horizontal and vertical) or let them
+       * be drawn solid to avoid implementing a whole line renderer
+       */
+      if (*ok && (hpen = ExtCreatePen (
+                           (win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
+                           (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
+                           &logbrush, 
+                           0, NULL)) == NULL)
+        WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
+    }
+  else
+    {
+      if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style,
+                           (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
+                           &logbrush, 
+                           win32_gc->pen_num_dashes,
+                           win32_gc->pen_dashes)) == NULL)
+        WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
+    }
   
   if (*ok && SelectObject (win32_gc->hdc, hpen) == NULL)
     WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE;
index 394348d3aa03a0debfc7f2a03602f1271a3500f3..a2858cbde581fd404b754d09624cf343c9a0dcd9 100644 (file)
@@ -2053,11 +2053,13 @@ gdk_keyval_name (guint keyval)
            
       return (gchar *) found->name;
     }
-  else
+  else if (keyval != 0)
     {
       sprintf (buf, "%#x", keyval);
       return buf;
     }
+
+  return NULL;
 }
 
 static int 
index 8b2d0c65a8ae2f38f19706c599f95ec525b62406..4b50fb518305c7f8956632ae368b60237736a391 100644 (file)
@@ -284,6 +284,8 @@ struct _GdkGCWin32
   gint graphics_exposures;
   gint pen_width;
   DWORD pen_style;
+  DWORD *pen_dashes;           /* use for PS_USERSTYLE or step-by-step rendering */
+  gint pen_num_dashes;
   HANDLE hwnd;                 /* If a HDC is allocated, for which window,
                                 * or what bitmap is selected into it
                                 */